/*
 Alan Fortes
 CPE 301
 DA 5, part 2

 The following C program uses an ATMega328p to
 control the speed of a stepper motor. This is done
 by using a voltage divider, with the resistor
 near ground being a potentiometer, to produce
 a varying voltage from the middle of the voltage
 divider. This voltage is then fed into the PC0(ADC0)
 pin, and converted into a value using ADC conversion.
 The values taken from the ADC register are then placed
 into an equation to find the appropriate value to place
 in the OCR1A register, to produce a changing duty cycle
 that will determine the speed of the motor.
*/

#define F_CPU 8000000UL
#include <avr/io.h>
#include <stdio.h>
#include <avr/interrupt.h>
#include <util/delay.h>

int main()
{
	double adcValue;
	int ocrValue;

	DDRB = 0xFF; //The B port is set to be output so the motor may be driven.
	TCCR1B = 0x0D; //TCCR1B is set to be ctc mode, with a prescaler of 1024.
	ADCSRA = 0x82; //ADC conversion is activated with an appropriate sampling rate.
	
	while(1){

		ADCSRA |= (1<<ADSC); //Single conversion is set to begin.
		while((ADCSRA&(1<<ADIF))==0){ //The ADC conversion has begun and will wait
									  //until the conversion has finished.
		}

	if(ADC < 70){ //The ranges are given so that the motor does not go to fast,
		
		ocrValue = 250;

		} else if(ADC > 540){//or too slow.
		
		ocrValue = 2000;
		
		}else{
		adcValue = ((ADC - 70) * 3.83) + 200; //If the value is between the extremes,
	    ocrValue = adcValue;                  //an appropriate speed will be given.
	}
 
	
		OCR1A = ocrValue; //The calculated value is placed in the OCR1A register.
		
	
			PORTB = 0X66;  //The series of events needed to drive 
                           //stepper motor are put into motion.			
			while((TIFR1 & (1<<OCF1A)) == 0){
			}
		
			TIFR1 |= (1 << OCF1A);
			PORTB = 0x33;
			while((TIFR1 & (1<<OCF1A)) == 0){
	        }
			 
			TIFR1 |= (1 << OCF1A);
			PORTB = 0x99;
			while((TIFR1 & (1<<OCF1A)) == 0){
			}
			 
			TIFR1 |= (1 << OCF1A);
			PORTB = 0xCC;
			while((TIFR1 & (1<<OCF1A)) == 0){
			}
			 
			TIFR1 |= (1 << OCF1A);
	
	}
	 
	return 0;
}